(import
 (except (rnrs base) let-values map)
 (only (guile)
       lambda* λ))

;;; ===============
;;; SUM OF PREFIXES
;;; ===============

;; This part introduces a function, which calculates the sum of the
;; prefix for each element in the given list.

;; My first attempt:

(define sum-of-prefixes-with-inner-function
  (λ (tup)

    (define iter
      (λ (tup prefix-sum)
        (cond
         [(null? tup)
          (cons prefix-sum '())]
         [else
          (cons prefix-sum
                (iter  (cdr tup)
                       (+ prefix-sum (car tup))))])))

    (cond
     [(null? tup) '()]
     [else
      (iter (cdr tup) (car tup))])))

;; USAGE:

(display
 (simple-format
  #f "(sum-of-prefixes-with-inner-function '(1 1 1 1 1)) -> ~a\n"
  (sum-of-prefixes-with-inner-function '(1 1 1 1 1))))

;; The book does not make use of inner definitions using
;; ~define~. Instead it uses additional functions defined separately:

(define sum-of-prefixes
  (λ (tup)
    ;; Start with a sum of 0, the neutral element of addition.
    (sum-of-prefixes-b 0 tup)))

(define sum-of-prefixes-b
  (λ (sonssf tup)
    (cond
     [(null? tup) '()]
     [else
      (cons (+ sonssf (car tup))
            (sum-of-prefixes-b (+ sonssf (car tup))
                               (cdr tup)))])))

;; USAGE: Let us try it:

(display
 (simple-format
  #f "(sum-of-prefixes '(1 1 1 1 1)) -> ~a\n"
  (sum-of-prefixes '(1 1 1 1 1))))

;; EXPLANATION:

;; ~sum-of-prefixes~ just like in my own solution takes only one
;; argument, so that the caller does not need to think about the
;; implementation detail. The interface is simple. The definition in
;; the book has advantages and disadvantages. An advantage is, that
;; the code is less nested. A disadvantage is, that
;; ~sum-of-prefixes-b~ pollutes the namespace of the module, in which
;; it is defined and serves no other purpose than being called by
;; ~sum-of-prefixes~.

;; The point the book makes is, that for recursive functions, which
;; need to know about previous arguments to the function, one can
;; define a helper function, which takes additional arguments. This is
;; stated in the Eleventh Commandment:

;; > Use additional arguments when a function needs to know what other
;; arguments to the function have been like so far.
